using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

using NSimpleDB.Service.Contract;
using Forum.Contracts;

namespace Forum.DataAccess.Retrievers
{
    class ParallelPostingRetriever : IPostingRetriever
    {
        #region IPostingRetriever Members

        public Posting[] Retrieve(IDataAccess da, ISimpleDBService db, Posting parent, string[] postingIds)
        {
            List<Posting> postings = new List<Posting>();

            if (postingIds.Length > 0)
            {
                Thread th = new Thread(
                    delegate()
                    {
                        AutoResetEvent[] retrieverThreadSignals = new AutoResetEvent[postingIds.Length];
                        for (int i = 0; i < postingIds.Length; i++)
                        {
                            retrieverThreadSignals[i] = new AutoResetEvent(false);
                            ThreadPool.QueueUserWorkItem(
                                delegate(object state)
                                {
                                    int j = (int)state;
                                    string id = postingIds[j];

                                    ISimpleDBAttribute[] attributes;
                                    attributes = db.GetAttributes(Mapping.Mapper.ForumsDomainName, id,
                                                                  "subject", "text", "createdAt", "createdBy");
                                    Posting p = Mapping.Mapper.MapAttributes2Posting(da, attributes, id, parent);

                                    lock (postings)
                                    {
                                        postings.Add(p);
                                    }

                                    retrieverThreadSignals[j].Set();
                                }, i);
                        }

                        WaitHandle.WaitAll(retrieverThreadSignals);
                    });
                th.IsBackground = true;
                th.Start();

                th.Join();
            }

            postings.Sort(delegate(Posting a, Posting b) { return a.CreatedAt.CompareTo(b.CreatedAt); });
            return postings.ToArray();
        }

        #endregion
    }
}
